package org.springblade.modules.ad.service.impl;


import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.ad.entity.AdGroup;
import org.springblade.modules.ad.entity.AdOU;
import org.springblade.modules.ad.entity.AdUser;
import org.springblade.modules.ad.service.AdGroupService;
import org.springblade.modules.ad.utils.LdapUtil;
import org.springblade.modules.ad.utils.Result;
import org.springblade.modules.dingtalk.entity.DeptSyncOU;
import org.springframework.ldap.InvalidAttributeValueException;
import org.springframework.ldap.NameAlreadyBoundException;
import org.springframework.ldap.NameNotFoundException;
import org.springframework.ldap.core.DirContextOperations;
import org.springframework.ldap.core.LdapTemplate;
import org.springframework.ldap.support.LdapNameBuilder;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.naming.Name;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.BasicAttributes;

import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

import static org.springblade.modules.ad.utils.LdapUtil.buildDn;

@Service
public class AdGroupServiceImpl implements AdGroupService {
	private final Logger logger = LoggerFactory.getLogger(getClass());

	@Resource
	private ThreadPoolTaskExecutor executor;
	@Resource
	private LdapTemplate ldapTemplate;



	@Override
	public boolean addAdGroup(AdOU group) {
		try {
			String adGroupName = AdGroup.getAdGroupName(group.getDeptId());
			Attributes attrs = new BasicAttributes();
			BasicAttribute ocAttr = new BasicAttribute("objectClass");
			ocAttr.add("top");
			ocAttr.add("group");
			attrs.put(ocAttr);
			attrs.put("name", adGroupName);
			attrs.put("description", group.getName());
			// 用户
//			if (CollectionUtil.isNotEmpty(group.getUserList())){
//				for (AdUser adUser:group.getUserList()) {
//					Name userDn = LdapUtil.buildDn(group.getBasePath(),adUser.getGivenName());
//					DirContextOperations ctxUser = ldapTemplate.lookupContext(userDn);
//					attrs.put("member", ctxUser.getStringAttribute("distinguishedname"));
//				}
//				// 下级域组
//				// attrs.put("member", ctxUser.getStringAttribute("distinguishedname"));
//			}
			ldapTemplate.bind(buildDn(group.getBasePath(), adGroupName), null, attrs);
			return true;
		} catch (Exception e) {
			if (e instanceof NameAlreadyBoundException){
				logger.info("该目录下，该用户已存在,异常信息:"+ e.getMessage());
				return false;
			}
			if (e instanceof NameNotFoundException){
				logger.info("请确认改ou目录已存在的情况下创建域组,异常信息:" + e.getMessage());
				return false;
			}
			if (e instanceof InvalidAttributeValueException){
				logger.info("用户属性值异常,异常信息:" + e.getMessage());
				return false;
			}
			e.printStackTrace();
			return false;
		}
	}


	@Override
	public void addUserToGroup(AdGroup adGroup) {
		try {
			// 域组或成员的dn
			Set<String> distinguishedNames = Sets.newHashSet();
			// 用户
			for (String userName : adGroup.getMembers()) {
				Name userDn = LdapUtil.buildDn(adGroup.getBasePath(), userName);
				DirContextOperations ctxUser = ldapTemplate.lookupContext(userDn);
				distinguishedNames.add(ctxUser.getStringAttribute("distinguishedname"));
			}
			// 组的dn
			String adGroupName;
			if (null != adGroup.getName()){
				adGroupName = adGroup.getName();
			}else {
				adGroupName = adGroup.getAdGroupName(adGroup.getDeptId());
			}
			Name groupDn = LdapUtil.buildDn(adGroup.getBasePath(), adGroupName);
			DirContextOperations ctxGroup = ldapTemplate.lookupContext(groupDn);
			for (String distinguishedName : distinguishedNames) {
				ctxGroup.addAttributeValue("member", distinguishedName);
			}
			ldapTemplate.modifyAttributes(ctxGroup);
		} catch (Exception e) {
			if (e instanceof NameNotFoundException) {
				logger.info("请确认改域组目录已存在的情况下添加,异常信息:" + e.getMessage());
				return;
			}
			e.printStackTrace();
		}
	}

	@Override
	public Result addUserToGroup(List<AdGroup> list) {
		for (AdGroup adGroup : list) {
			executor.execute(() -> addUserToGroup(adGroup));
		}
		return Result.of().success();
	}


	@Override
	public void removeUserToGroup(LinkedList<String> basePath, String username) {
		Name groupDn = LdapNameBuilder.newInstance().add("ou","NiceTuan").add("cn","nameGroup02").build();  // 组的dn
		Name userDn = LdapNameBuilder.newInstance().add("ou","NiceTuan").add("cn","yonghu01").build();  // 成员的dn
		DirContextOperations ctxGroup = ldapTemplate.lookupContext(groupDn);
		DirContextOperations ctxUser = ldapTemplate.lookupContext(userDn);
		// uniqueMember
		ctxGroup.removeAttributeValue("member", ctxUser.getStringAttribute("distinguishedname"));
		ldapTemplate.modifyAttributes(ctxGroup);
	}
}
